/**
 * 全局错误处理插件
 * 统一处理所有错误并返回标准化的错误响应
 */

import { FastifyPluginAsync, FastifyError, FastifyRequest, FastifyReply } from 'fastify'
import fp from 'fastify-plugin'
import {
    BusinessError,
    UnauthorizedError,
    PermissionError,
    NotFoundError,
    ValidationError as CustomValidationError,
    ConflictError,
    CheckInError
} from '@services/common/errors'

/**
 * 标准错误响应格式
 */
interface ErrorResponse {
    success: false
    error: string
    code?: string
    statusCode: number
    details?: any
    timestamp: string
    path: string
}

/**
 * 创建标准错误响应
 */
function createErrorResponse(
    error: Error,
    statusCode: number,
    request: FastifyRequest,
    code?: string,
    details?: any
): ErrorResponse {
    return {
        success: false,
        error: error.message,
        code,
        statusCode,
        details,
        timestamp: new Date().toISOString(),
        path: request.url
    }
}

/**
 * 错误处理器
 */
async function errorHandler(error: FastifyError | Error, request: FastifyRequest, reply: FastifyReply): Promise<void> {
    // 1. 处理业务异常
    if (error instanceof BusinessError) {
        const response = createErrorResponse(error, error.statusCode, request, error.code.toString())
        return reply.status(error.statusCode).send(response)
    }

    // 2. 处理认证异常
    if (error instanceof UnauthorizedError) {
        const response = createErrorResponse(error, 401, request, 'UNAUTHORIZED')
        return reply.status(401).send(response)
    }

    // 3. 处理权限异常
    if (error instanceof PermissionError) {
        const response = createErrorResponse(error, 403, request, 'FORBIDDEN')
        return reply.status(403).send(response)
    }

    // 4. 处理资源未找到异常
    if (error instanceof NotFoundError) {
        const response = createErrorResponse(error, 404, request, 'NOT_FOUND')
        return reply.status(404).send(response)
    }

    // 5. 处理验证异常
    if (error instanceof CustomValidationError) {
        const details = error.fields ? { fields: error.fields } : undefined
        const response = createErrorResponse(error, 422, request, 'VALIDATION_ERROR', details)
        return reply.status(422).send(response)
    }

    // 6. 处理冲突异常
    if (error instanceof ConflictError) {
        const response = createErrorResponse(error, 409, request, 'CONFLICT')
        return reply.status(409).send(response)
    }

    // 7. 处理签到异常
    if (error instanceof CheckInError) {
        const details = error.failedConditions ? { failedConditions: error.failedConditions } : undefined
        const response = createErrorResponse(error, 400, request, 'CHECKIN_ERROR', details)
        return reply.status(400).send(response)
    }

    // 8. 处理 Fastify 验证错误
    const fastifyError = error as FastifyError
    if (fastifyError.validation) {
        const response = createErrorResponse(error, 400, request, 'VALIDATION_ERROR', fastifyError.validation)
        return reply.status(400).send(response)
    }

    // 9. 处理 HTTP 错误
    if (fastifyError.statusCode) {
        const response = createErrorResponse(error, fastifyError.statusCode, request, fastifyError.code)
        return reply.status(fastifyError.statusCode).send(response)
    }

    // 10. 处理数据库错误（Prisma）
    if (error.constructor.name.includes('Prisma')) {
        request.log.error({ error: error.message, stack: error.stack }, '数据库错误')

        const response = createErrorResponse(new Error('数据库操作失败'), 500, request, 'DATABASE_ERROR')
        return reply.status(500).send(response)
    }

    // 11. 处理未知错误
    request.log.error({ error: error.message, stack: error.stack }, '未知错误')

    const response = createErrorResponse(new Error('服务器内部错误'), 500, request, 'INTERNAL_SERVER_ERROR')
    return reply.status(500).send(response)
}

/**
 * Not Found 处理器
 */
async function notFoundHandler(request: FastifyRequest, reply: FastifyReply): Promise<void> {
    const response: ErrorResponse = {
        success: false,
        error: `路由 ${request.method} ${request.url} 不存在`,
        code: 'NOT_FOUND',
        statusCode: 404,
        timestamp: new Date().toISOString(),
        path: request.url
    }

    return reply.status(404).send(response)
}

/**
 * 错误处理插件
 */
const errorHandlerPlugin: FastifyPluginAsync = async (fastify, opts) => {
    // 注册全局错误处理器
    fastify.setErrorHandler(errorHandler)

    // 注册 404 处理器
    fastify.setNotFoundHandler(notFoundHandler)

    // 添加请求日志（开发环境）
    if (process.env.NODE_ENV === 'development') {
        fastify.addHook('onRequest', async (request, reply) => {
            request.log.info(`${request.method} ${request.url}`)
        })
    }

    // 添加响应日志（开发环境）
    if (process.env.NODE_ENV === 'development') {
        fastify.addHook('onResponse', async (request, reply) => {
            request.log.info(`${request.method} ${request.url} - ${reply.statusCode}`)
        })
    }

    // 添加错误日志（所有环境）
    fastify.addHook('onError', async (request, reply, error) => {
        request.log.error(
            {
                url: request.url,
                method: request.method,
                error: error.message,
                stack: error.stack
            },
            '请求错误'
        )
    })
}

export default fp(errorHandlerPlugin, {
    name: 'error-handler',
    dependencies: []
})
